package com.xiaoyu.lanling.feature.fate

import `in`.srain.cube.util.internal.AppConsumer
import android.Manifest
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import com.amap.api.location.AMapLocation
import com.tbruyelle.rxpermissions2.RxPermissions
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.event.AppEventBus
import com.xiaoyu.base.event.SimpleEventHandler
import com.xiaoyu.base.utils.RxUtils
import com.xiaoyu.base.utils.extensions.setOnClickDebounceListener
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.common.Constant.RequestCode.LOCATION
import com.xiaoyu.lanling.event.fate.MainFatePreferenceUpdateEvent
import com.xiaoyu.lanling.event.user.UserSetProfileEvent
import com.xiaoyu.lanling.feature.fate.controller.MainFateUserListViewController
import com.xiaoyu.lanling.feature.fate.data.MainFateUserListData
import com.xiaoyu.lanling.feature.fate.model.MainFateUserItem
import com.xiaoyu.lanling.feature.location.LocationData
import com.xiaoyu.lanling.feature.location.LocationHelper
import com.xiaoyu.lanling.router.Router
import com.xiaoyu.lanling.view.OnShowFragment
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.fragment_main_fate.*
import kotlinx.android.synthetic.main.view_main_fate_without_permission.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class MainFateFragment : OnShowFragment() {

    private val requestTag = Any()

    private var mPermissionDisposable: Disposable? = null
    private var mSvgaDisposable: Disposable? = null

    lateinit var listController: MainFateUserListViewController

    companion object {
        const val TOP_1_INDEX = 0
        const val TOP_2_INDEX = 1
        const val TOP_3_INDEX = 2
        const val MAX_TOP_COUNT = 3
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_main_fate, container, false)
    }

    override fun onViewCreatedSafelyAfterAppFinishInit(view: View, savedInstanceState: Bundle?) {
        initView()
        initBind()
        initEvent()
        initData()
        initPermission()
    }

    override fun onDestroy() {
        super.onDestroy()
        RxUtils.disposable(mSvgaDisposable, mPermissionDisposable)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == LOCATION) {
            updatePermissionLayout()
            requestLocation()
        }
    }

    private fun initView() {
        updatePermissionLayout()
    }

    private fun initEvent() {
        AppEventBus.bindContainerAndHandler(this, object : SimpleEventHandler() {
            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: MainFatePreferenceUpdateEvent) {
                loadFirstPageData()
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: UserSetProfileEvent) {
                if (event.isFailed) {
                    return
                }
                loadFirstPageData()
            }
        })
    }

    private fun initBind() {
        permission_button?.setOnClickDebounceListener { v ->
            if (enableLocation()) {
                requestLocationEvenIfNotAskAgain()
            } else {
                val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                startActivityForResult(intent, LOCATION)
            }
        }
    }

    private fun initData() {
        val listData = MainFateUserListData<MainFateUserItem, Any>()

        context?.let {
            listController = MainFateUserListViewController.create(it, listData, swipe_refresh_layout, recyclerview)
        }
    }

    private fun initPermission() {
        requestLocation()
    }

    private fun loadFirstPageData() {
        val locatable = isLocatable()
        if (locatable) {
            listController.loadFirstPageData()
        }
    }

    private fun isLocatable(): Boolean {
        return enableLocation() && hasLocationPermission();
    }

    private fun enableLocation(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            val locationManager = (activity?.getSystemService(LOCATION_SERVICE) as? LocationManager)
            return locationManager?.isLocationEnabled == true
        } else {
            var locationMode = 0
            try {
                locationMode = Settings.Secure.getInt(context?.contentResolver, Settings.Secure.LOCATION_MODE)
            } catch (t: Throwable) {
                t.printStackTrace()
            } finally {
                return locationMode != Settings.Secure.LOCATION_MODE_OFF
            }
        }
    }

    private fun hasLocationPermission(): Boolean {
        return ActivityCompat.checkSelfPermission(AppContext.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(AppContext.getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
    }

    private fun updatePermissionLayout() {
        val locatable = isLocatable()
        permission_layout?.visibility = if (locatable) View.GONE else View.VISIBLE
        swipe_refresh_layout?.isRefreshing = false
        swipe_refresh_layout?.isEnabled = locatable
    }

    private fun requestLocationEvenIfNotAskAgain() {
        if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
            requestLocation()
        } else {
            showRequestPermissionDialog()
        }
    }

    private fun showRequestPermissionDialog() {
        activity?.let {
            AlertDialog.Builder(it)
                    .setTitle(getString(R.string.fate_permission_setting_dialog_title))
                    .setMessage(getString(R.string.fate_permission_setting_dialog_message))
                    .setPositiveButton(getString(R.string.fate_permission_setting_dialog_positive_button)) { _, _ ->
                        Router.instance.gotoApplicationDetailsSettings(this)
                    }
                    .setNegativeButton(AppContext.getString(R.string.action_cancel)) { _, _ -> }
                    .show()
        }
    }

    private fun requestLocation() {
        activity?.let {
            mPermissionDisposable = RxPermissions(it)
                    .request(Manifest.permission.ACCESS_FINE_LOCATION)
                    .subscribe { granted ->
                        if (granted) {
                            getLocation()
                        }
                        updatePermissionLayout()
                    }
        }
    }

    private fun getLocation() {
        LocationHelper().getLocation(object : AppConsumer<AMapLocation> {
            override fun accept(location: AMapLocation?) {
                if (location == null || location.longitude <= 0 || location.latitude <= 0) {
                    return
                }
                LocationData.getAddress(requestTag, location.longitude, location.latitude)
            }
        })
    }
}